Repository navigation
fix(concerto-cto): safely handle null default values and validator bounds in Printer - #1601
Siddharth-Dangi wants to merge 1 commit into
Conversation
|
Hi team (@jamieshorten @mttrbrts) — friendly check-in on this PR. All core builds, unit tests, DCO, and CodeQL security checks are passing green. (The external conformance test failure is the known upstream expectation mismatch on map value types present across main). Happy to address any feedback or adjust anything whenever you have a moment to review. Thank you! |
|
Thanks for the PR, @Siddharth-Dangi, and for the patience while it waited. Handling Drafted by an Accord Project agent, reviewed by a maintainer. |
8f7c401 to
62fe262
Compare
|
Thanks @mira-accord-project! I've cleanly rebased the branch onto the latest upstream |
62fe262 to
f0a7dfe
Compare
…unds in Printer Metamodel AST instances can represent optional or unbounded properties using explicit null values (e.g. deserialized from JSON metamodels). Previously, Printer.toCTO only checked !== undefined in several places, causing multiple defects: - defaultValue: null on IntegerProperty or LongProperty crashed with TypeError (calling null.toString()) - defaultValue: null on DoubleProperty emitted default=0.0 - defaultValue: null on StringProperty, DateTimeProperty, and ObjectProperty emitted default="null" - lower: null or upper: null on IntegerDomainValidator or LongDomainValidator emitted invalid CTO syntax range=[null, ...] - lower: null on DoubleDomainValidator emitted range=[0.0, ...] - minLength: null or maxLength: null on StringLengthValidator emitted length=[null, ...] - minSize: null or maxSize: null on CollectionSizeValidator emitted size=[null, ...] - flags: null on StringRegexValidator threw in RegExp constructor, bypassing forward slash escaping - pattern: null on StringRegexValidator emitted regex=/null/ - all null/omitted bounds on StringLengthValidator emitted length=[,], which causes a syntax error in Parser.parse - all null/omitted bounds on domain and size validators emitted range=[,] and size=[,], which fail model introspection validation - ObjectProperty default values containing quotes were interpolated without escaping, breaking parser syntax - empty decorators arrays emitted spurious newlines and whitespace indentation Use NullUtil.isNull to safely ignore null bounds and defaults while preserving falsy non-null values (0, false, ""). Guard validators to only emit clauses when at least one bound exists. Escape ObjectProperty default values with toStringLiteral. Safely handle empty decorators and clean regex flags so pattern normalization succeeds. Signed-off-by: Siddharth-Dangi <mr.siddharthdangi@gmail.com>
f0a7dfe to
b8e4d7e
Compare
Summary
In
@accordproject/concerto-cto,Printer.toCTOconverts a Concerto Metamodel AST into CTO text format. When processing an AST where optional fields have explicitnullvalues or omitted bounds (such as ASTs deserialized from JSON models or generated programmatically):IntegerPropertyandLongProperty,Printer.toCTOcalledmm.defaultValue.toString()because it checked!== undefined. IfdefaultValue: null, it crashed withTypeError: Cannot read properties of null (reading 'toString').StringLengthValidator, if both bounds were null or omitted,Printer.toCTOemittedlength=[,], which fails parsing withAt least one length bound must be specified.DoubleDomainValidator,IntegerDomainValidator,LongDomainValidator, andCollectionSizeValidator, null or omitted bounds emittedrange=[null, ...]orrange=[,]/size=[,], which fail model validation withIllegalModelException.DoubleDomainValidator,toDoubleString(null)evaluatedNumber(null)as0, turning unbounded lower bounds into0.0.ObjectPropertydefault values containing quotes were interpolated directly without escaping (default="${mm.defaultValue}"), breaking CTO parsing.decorators: []emitted spurious newlines and whitespace indentation.flags: nullthrew inRegExp, bypassing pattern normalization and slash escaping, whilepattern: nullfabricatedregex=/null/.Solution
NullUtil.isNullfrom@accordproject/concerto-utilto safely guard againstnullandundefinedwhile preserving valid falsy values (0,0.0,"",false).range,length, andsizevalidators to only emit clauses when at least one bound exists.ObjectPropertydefault values withtoStringLiteral, ensuring quotes and backslashes round-trip cleanly.decoratorsFromMetaModelwhen the decorators array is empty.flags || undefined) and guard pattern so regex normalization and forward-slash escaping succeed cleanly.packages/concerto-cto/test/printer.jsachieving 100% statement, branch, function, and line coverage.Checklist
concerto-cto)licchk), and JSDoc pass cleanlySigned-off-by)